package com.gitee.huanminabc.utils_tools.web_base.utils;

import com.gitee.huanminabc.jcommon.exception.BizException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
@Slf4j
/**
 * 游览器上传文件到服务器中
 */
public class FileWebUpload {
    private static final Logger logger = LoggerFactory.getLogger(FileWebUpload.class);



    @SneakyThrows
    public static  void  fileUpload(String directory,HttpServletRequest request)  {
        fileUpload(directory,null,request);
    }
    /**
     *
     * @param directory 文件上传的目录
     * @param fileName  文件名称  ,如果为null 那么默认为上传的文件名称
     * @param request
     */
    @SneakyThrows
    public static  void  fileUpload(String directory,String fileName,HttpServletRequest request)  {
        //上传的位置   这句代码就是将文件上传到当前服务器的根目录下uploads文件夹里添加
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
        //拿到所有上传的文件对象
        for (Map.Entry<String, MultipartFile> stringMultipartFileEntry : multiFileMap.toSingleValueMap().entrySet()) {
            MultipartFile uploadFile = stringMultipartFileEntry.getValue();
            //判断文件上传表单是否是空
            boolean empty = uploadFile.isEmpty();
            //如果是空 的file表单那么 跳过
            if (!empty) {
                String filename = uploadFile.getOriginalFilename();
                if (fileName!=null){
                    filename=fileName;
                }
                //完成文件上传
                uploadFile.transferTo(new File(directory, filename));
                logger.info("文件上传后的路径" + new File(directory, filename).getAbsolutePath());
            } else {
                throw new Exception("上传的文件是空的");
            }
        }

    }


    //前端提供MultipartFile[]  我们内置文件上传   多个文件同时上传  配合 controller 层使用 使用
    public static String  httpClientUploadFile(String url, MultipartFile[] files) {
        //        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = createSSLClientDefault(); //跳过证书验证
        String result = "";
        try {
            //文件名
//            String fileName = file.getName();
            HttpPost httpPost = new HttpPost(url);

            //HttpEntity builder
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //字符编码
            builder.setCharset(StandardCharsets.UTF_8);
            //模拟浏览器
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

            for (MultipartFile file : files) {
                InputStream in = file.getInputStream();
                builder.addBinaryBody("file",in, ContentType.MULTIPART_FORM_DATA, file.getOriginalFilename());
            }

            //HttpEntity
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            // 执行提交
            HttpResponse response = httpClient.execute(httpPost);
            //响应
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);

            }
        } catch (Exception e) {
            throw new BizException(e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                throw new BizException(e);
            }
        }
        return result;
    }

    // //前端提供MultipartFile 单个文件上传   配合 controller 层使用 使用
    public static String httpClientUploadFile(String url, MultipartFile file) {
        //        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = createSSLClientDefault(); //跳过证书验证
        String result = "";
        try {
            //文件名
//            String fileName = file.getName();
            HttpPost httpPost = new HttpPost(url);
            //HttpEntity builder
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //字符编码
            builder.setCharset(StandardCharsets.UTF_8);
            //模拟浏览器
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            InputStream in = file.getInputStream();
            builder.addBinaryBody("file",in,ContentType.MULTIPART_FORM_DATA, file.getOriginalFilename());
            //HttpEntity
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            // 执行提交
            HttpResponse response = httpClient.execute(httpPost);
            //响应
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            throw new BizException(e);
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                throw new BizException(e);
            }
        }
        return result;
    }


    //跳过证书验证
    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
            log.error("",e);
        }
        return HttpClients.createDefault();

    }



}
